﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Reflection;

namespace ValidationFramework.Configuration.Xml
{
	public interface IXmlAddRuleExpression
	{
		/// <summary>
		/// Add validation from a particular XML file.
		/// </summary>
		/// <param name="xmlFileInfo">The <see cref="FileInfo"/> to the XML data.</param>
		/// <exception cref="ArgumentNullException"><paramref name="xmlFileInfo"/> is null.</exception>
		/// <exception cref="FileNotFoundException">The file represented by <paramref name="xmlFileInfo"/> cannot be found.</exception>
		/// <exception cref="WebException">The remote filename cannot be resolved.-or-An error occurred while processing the request.</exception>
		/// <exception cref="DirectoryNotFoundException">Part of the filename or directory cannot be found.</exception>
		void AddXmlFile(FileInfo xmlFileInfo);

		/// <summary>
		/// Add validation from a particular XML file.
		/// </summary>
		/// <param name="xmlFileUrl">The URL for the file containing the XML data.</param>
		/// <exception cref="ArgumentNullException"><paramref name="xmlFileUrl"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="xmlFileUrl"/> is a <see cref="string.Empty"/>.</exception>
		/// <exception cref="FileNotFoundException"><paramref name="xmlFileUrl"/> cannot be found.</exception>
		/// <exception cref="WebException">The remote filename cannot be resolved.-or-An error occurred while processing the request.</exception>
		/// <exception cref="DirectoryNotFoundException">Part of the filename or directory cannot be found.</exception>
		/// <exception cref="UriFormatException"><paramref name="xmlFileUrl"/> is not a valid URI.</exception>
		void AddXmlFile(string xmlFileUrl);

		/// <summary>
		/// Add all validation definitions from a directory tree.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Assume that any file named <c>*.validation.xml</c> is a validation definition document.
		/// </para>
		/// <para>
		/// This method is recursive.
		/// </para>
		/// </remarks>
		/// <param name="directoryInfo">a directory</param>
		/// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is null.</exception>
		/// <exception cref="DirectoryNotFoundException">The path encapsulated in <paramref name="directoryInfo"/> is invalid, such as being on an unmapped drive.</exception>
		/// <exception cref="FileNotFoundException">A file in one of the directories cannot be found.</exception>
		/// <exception cref="WebException">The remote filename cannot be resolved.-or-An error occurred while processing the request.</exception>
		/// <exception cref="DirectoryNotFoundException">Part of the filename or directory cannot be found.</exception>
		void AddDirectory(DirectoryInfo directoryInfo);

		/// <summary>
		/// Add validation definitions from a <c>string</c>
		/// </summary>
		/// <param name="xml">The <see cref="string"/> containing the XML data.</param>
		/// <exception cref="ArgumentNullException"><paramref name="xml"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="xml"/> is a <see cref="string.Empty"/>.</exception>
		/// <exception cref="XmlException"><paramref name="xml"/> is not a valid <see cref="XmlNodeType.Document"/>.</exception>
		void AddXmlString(string xml);

		/// <summary>
		/// Adds the validation in the <see cref="XmlTextReader"/> after validating it against the validationFramework-validationDefinition-1.5 schema.
		/// </summary>
		/// <param name="xmlReader">The XmlTextReader that contains the validation.</param>
		/// <exception cref="ArgumentNullException"><paramref name="xmlReader"/> is null.</exception>
		void AddXmlReader(XmlReader xmlReader);

		/// <summary>
		/// Read validation definitions from a URL.
		/// </summary>
		/// <param name="url">a URL</param>
		/// <exception cref="ArgumentNullException"><paramref name="url"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="url"/> is a <see cref="string.Empty"/>.</exception>
		/// <exception cref="FileNotFoundException"><paramref name="url"/> cannot be found.</exception>
		/// <exception cref="WebException">The remote filename cannot be resolved.-or-An error occurred while processing the request.</exception>
		/// <exception cref="DirectoryNotFoundException">Part of the filename or directory cannot be found.</exception>
		/// <exception cref="UriFormatException"><paramref name="url"/> is not a valid URI.</exception>
		void AddUrl(string url);

		/// <summary>
		/// Read validation definitions from a <see cref="Uri"/>.
		/// </summary>
		/// <param name="uri">a <see cref="Uri" /> to read the mappings from.</param>
		/// <returns>This configuration object.</returns>
		/// <exception cref="ArgumentNullException"><paramref name="uri"/> is null.</exception>
		void AddUrl(Uri uri);
#if (!SILVERLIGHT)
		/// <summary>
		/// Read validation definitions from an <see cref="XmlDocument"/>.
		/// </summary>
		/// <param name="xmlDocument">A loaded <see cref="XmlDocument"/> that contains the validation.</param>
		/// <exception cref="ArgumentNullException"><paramref name="xmlDocument"/> is null.</exception>
		void AddDocument(XmlDocument xmlDocument);
#endif
		/// <summary>
		/// Add validation definition from a <see cref="Stream"/>.
		/// </summary>
		/// <param name="xmlInputStream">The stream containing XML</param>
		/// <remarks>
		/// The <see cref="Stream"/> passed in through the parameter <c>xmlInputStream</c> is not <b>guaranteed</b> to be cleaned up by this method.  It is the callers responsibility to ensure that the <c>xmlInputStream</c> is properly handled when this method completes.
		/// </remarks>
		/// <exception cref="ArgumentNullException"><paramref name="xmlInputStream"/> is null.</exception>
		void AddInputStream(Stream xmlInputStream);

		/// <summary>
		/// Adds the validation definitions in the Resource of the <see cref="Assembly"/>.
		/// </summary>
		/// <param name="path">The path to the Resource file in the <see cref="Assembly"/></param>
		/// <param name="assembly">The <see cref="Assembly"/> that contains the Resource file.</param>
		/// <exception cref="ArgumentNullException"><paramref name="assembly"/> is null.</exception>
		/// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="path"/> is a <see cref="string.Empty"/>.</exception>
		/// <exception cref="FileLoadException"><paramref name="path"/> could not be loaded.</exception>
		/// <exception cref="FileNotFoundException"><paramref name="path"/> was not found.</exception>
		/// <exception cref="BadImageFormatException"><paramref name="assembly"/> is not a valid assembly.</exception>
		void AddResourceFromAssembly(Assembly assembly, string path);

		/// <summary>
		/// Adds all of the Assembly's Resource files that end with "<c>.validation.xml</c>"
		/// </summary>
		/// <param name="assemblyName">The name of the <see cref="Assembly"/> to load.</param>
		/// <remarks>
		/// <para>The <see cref="Assembly"/> must be in the local bin, probing path, or GAC so that the <see cref="Assembly"/> can be loaded by name.  
		/// If these conditions are not satisfied then your code should load the <see cref="Assembly"/> and call the override <see cref="AddAssembly(Assembly)"/> instead.</para> 
		/// <para>This method is case sensitive, hence the resource files must end with lower case "<c>.validation.xml</c>".</para>
		/// </remarks>
		/// <exception cref="ArgumentNullException"><paramref name="assemblyName"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="assemblyName"/> is a <see cref="string.Empty"/>.</exception>
		/// <exception cref="FileLoadException"><paramref name="assemblyName"/> was found but could not be loaded.</exception>
		/// <exception cref="FileNotFoundException"><paramref name="assemblyName"/> is not found.</exception>
		/// <exception cref="BadImageFormatException"><paramref name="assemblyName"/> is not a valid assembly.</exception>
		void AddResourceFromAssembly(string assemblyName);

		/// <summary>
		/// Adds all of the <paramref name="assembly"/> resource files that end with "<c>.validation.xml</c>".
		/// </summary>
		/// <remarks>This method is case sensitive, hence the resource files must end with lower case "<c>.validation.xml</c>".</remarks>
		/// <param name="assembly">The <see cref="Assembly"/> to load.</param>
		/// <exception cref="ArgumentNullException"><paramref name="assembly"/> is null.</exception>
		void AddResourceFromAssembly(Assembly assembly);
	}
}
